package emulator.GUI.display;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.WritableRaster;
import java.util.Observable;
import java.util.Observer;

public class VicScreen extends BufferedImage implements VicDisplay {
	private Dimension screen_size;
	private Dimension pixel_size;
	private int lock = 0;
	private int [] colors = {
			0x000000, 0xFFFFFF, 0xF00000, 0x00F0F0,
			0x600060, 0x00A000, 0x0000F0, 0xD0D000,
			0xC0A000, 0xFFA000, 0xF08080, 0x00FFFF,
			0xFF00FF, 0x00FF00, 0x00A0FF, 0xFFFF00
	/* int [] colors = {  --- C-64 colors ---
			0x000000, 0xFFFFFF, 0x68372B, 0x70A4B2,
			0x6F3D86, 0x588D43, 0x352879, 0xB8C76F,
			0x6F4F25, 0x433900, 0x9A6759, 0x444444,
			0x6C6C6C, 0x9AD284, 0x6C5EB5, 0x959595 */
	};
	private ObservableImpl observable = new ObservableImpl();
	private int[] image_data;

	public VicScreen(int pixel_width, int width, int pixel_height, int height) {
		super(width, height, BufferedImage.TYPE_INT_ARGB);
		pixel_size = new Dimension(pixel_width, pixel_height);
		screen_size = new Dimension(width, height);
		// colors to ARGB
		for (int i = 0; i < colors.length; i++)
			colors[i] |= 0xFF000000;
		// image buffer
	    WritableRaster wRas = getRaster();
	    DataBufferInt dbInt = (DataBufferInt) wRas.getDataBuffer();
	    image_data = dbInt.getData(0);
	}

	public synchronized void lock()
	{
		while (lock > 0)
			try {
				wait();
			} catch (InterruptedException e) {
			}
		lock++;
	}
	
	public synchronized void unlock()
	{
		lock--;
		notifyAll();
	}
	
	/* (non-Javadoc)
	 * @see emulator.GUI.VicDisplay#putPixel(int, int, int)
	 */
	public void putPixel(int x, int y, int color)
	{
		putPixel(x, y, color, 1);
	}

	@Override
	public void putPixel(int x, int y, int color, int x_width) {
		lock();
		int line_start = y*pixel_size.height*screen_size.width +
						 x*pixel_size.width;
		for (int i_y = 0; i_y < pixel_size.height; i_y++)
		{
			int index = line_start;
			for (int i_x = 0; i_x < x_width*pixel_size.width; i_x++)
				image_data[index++] = colors[color&0x0f];
			line_start += screen_size.width;
		}		
		unlock();
	}
	
	@Override
	public void showScreen() {
		observable.doNotify();
	}

	/**
	 * @param arg0
	 * @see java.util.Observable#addObserver(java.util.Observer)
	 */
	public void addObserver(Observer arg0) {
		observable.addObserver(arg0);
	}
	
	class ObservableImpl extends Observable {
		public void doNotify()
		{
			setChanged();
			notifyObservers();
		}
	}

}
